﻿using Microsoft.Owin.Security.Infrastructure;
using SimpleInjector;
using System;
using System.Threading.Tasks;

namespace Sustainalytics.Auth.Service.OAuth
{
    /// <summary>
    /// Since this class is only instantated once at startup
    /// and we need to get new instaces for mongo collections based on the database switch between A/B
    /// we inject the container and use it as a service locator (even if this is an anti-pattern in different contexts)
    /// </summary>
    public class CustomRefreshTokenProvider : AuthenticationTokenProvider
    {
        private readonly Container _container;

        public CustomRefreshTokenProvider(Container container)
        {
            _container = container;
        }

        public override async Task CreateAsync(AuthenticationTokenCreateContext context)
        {
            var refreshToken = CreateRefreshToken();

            context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;
            context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

            refreshToken.ProtectedTicket = context.SerializeTicket();

            await _container.GetInstance<RefreshTokenRepository>().AddAsync(refreshToken);

            context.SetToken(refreshToken.Id.ToString("n"));
        }

        public override async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
        {
            

            var refreshTokenRepository = _container.GetInstance<RefreshTokenRepository>();
            var refreshToken = await refreshTokenRepository.GetByIdAsync(context.Token);

            if (refreshToken != null)
            {
                context.DeserializeTicket(refreshToken.ProtectedTicket);
                await refreshTokenRepository.RemoveAsync(context.Token);
            }
        }

        private static RefreshToken CreateRefreshToken()
        {
            return new RefreshToken
            {
                Id = Guid.NewGuid(),
                IssuedUtc = DateTime.UtcNow,
                ExpiresUtc = DateTime.UtcNow.AddDays(7),
            };
        }
    }
}
